home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
001
/
comm.c
< prev
next >
Wrap
Text File
|
1985-06-03
|
5KB
|
309 lines
COMM.C.1
/* NOTE: this code is indented using tabs set every 4 columns, not 8. */
/*
* Rudimentary communication program; written in C with I/O
* routines in assembler, using "#asm" construct in DeSmet C.
*/
#define TRUE 1
#define FALSE 0
#define NULL 0
#define comm_stat head!=tail
int head=0,
tail=0;
char comm_buffer[8192];
main()
{
char commget();
int c,
echo=FALSE,
verbose=FALSE;
initcomm();
goto inside;
while((c=my_ci())<256) /* alt's and function keys are >=256 */
{
commput(c);
if(echo)
my_co(c);
inside: while(my_stat()==0)
if(comm_stat)
if(is_nice(c=commget()))
my_co(c);
else
if(verbose)
{
my_co('^');
my_co(127&(c+'@'));
}
}
switch(c>>8) /* process function key */
{
case '\060': /* b send break */
make_break();
my_puts("** break **\n");
break;
case '\022': /* e echo toggle */
echo = !echo;
if(echo)
my_puts("** echo on **\n");
else
my_puts("** echo off **\n");
break;
case '\020': /* q quit */
my_puts("** returning to DOS **\n");
goto byebye;
case '\057': /* v verbose */
verbose = !verbose;
if(verbose)
my_puts("** verbose on **\n");
else
my_puts("** verbose off **\n");
break;
}
goto inside;
byebye:
killcomm();
}
initcomm()
{
#asm
; initialize communication port,
; and install interrupt handler
; save dseg for interrupt handler
mov ax,ds
mov cs:dssave,ax
; set int vector to my handler
push ds
xor ax,ax
mov ds,ax
mov [30h],offset handler
mov ax,cs
mov [32h],ax
pop ds
; assert DTR, RTS, and OUT2
mov dx,3fch
mov al,11
out dx,al
; enable interrupts for data ready
mov dx,3f9h
mov al,1
out dx,al
; clear any outstanding int
mov dx,3f8h
in al,dx
; enable interrupts
sti
; enable IRQ4 on 8259A
in al,21h
and al,0efh
out 21h,al
; and return
jmp init_finis
dssave: dw 0
handler:
push ds
push ax
push dx
push bx
; restore appropriate dseg
mov ax,cs:dssave
mov ds,ax
; grab the byte from comm port
mov dx,3f8h
in al,dx
; put it in the buffer
mov bx,tail_
mov comm_buffer_[bx],al
; tail=tail+1 (mod 8192)
inc bx
cmp bx,8192
jl handler_around
xor bx,bx
handler_around:
mov tail_,bx
; tell the 8259A EOI
mov dx,20h
mov al,32
out dx,al
pop bx
pop dx
pop ax
pop ds
; reenable interrupts
sti
iret
init_finis:
#
}
commput(c)
int c;
{
#asm
; put the character out the port
mov dx,3f8h
mov ax,[bp+4]
out dx,al
#
}
char commget()
{
char temp;
temp=comm_buffer[head++];
head%=8192;
return(temp);
}
killcomm()
{
#asm
; disconnect the interrupt handler
in al,21h
or al,10h
out 21h,al
#
}
make_break()
{
#asm
; set bit on LCR
mov dx,3fbh
in al,dx
push ax
or al,40h
out dx,al
; wait a wee bit (~200 ms)
mov bx,8
outer:
mov cx,7000
tight:
loop tight
dec bx
jnz outer
; and turn break back off
pop ax
out dx,al
#
}
is_nice(c) /* true for those characters that "should" be received */
char c;
{
c&=127;
if(c>=' ' && c<='~') /* printable */
return(TRUE);
if(c>6 && c<11) /* BEL, BS, HT, LF */
return(TRUE);
if(c==13 || c==27) /* CR, ESC */
return(TRUE);
return(FALSE);
}
my_puts(s) /* puts, using my_co() */
char *s;
{
while(*s)
{
if(*s=='\n')
my_co('\r');
my_co(*(s++));
}
}
my_co(c) /* character output, smaller and faster than DeSmet's,
using DOS function call 2.00 */
char c;
{
#asm
mov ah,2
mov dx,[bp+4]
int 21h
#
}
my_stat() /* true if character is ready from keyboard */
{
#asm
mov ah,1
int 16h
jz stat_no_char
mov ax,1
jmp stat_finis
stat_no_char:
xor ax,ax
stat_finis:
#
}
my_ci() /* get character from keyboard, using BIOS function call */
{
#asm
xor ah,ah
int 16h
or al,al
jz my_ci_finis
xor ah,ah
my_ci_finis:
#
}
------------------------------------------------------------------------------
The termcap for DOS 2.00 with ansi device driver follows:
------------------------------------------------------------------------------
pm|pcmon|IBM-PC using DOS 2.00 ansi device driver (monochrome)|\
:am:bc=^H:bw:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:co#80:cr=^M:\
:do=^J:ho=\E[H:kb=^H:li#25:ll=\E[25H:nd=\E[C:\
:pt:se=\E[0m:so=\E[1m:ta=^I:up=\E[A:xt:
pc|pccol|IBM-PC using DOS 2.00 ansi device driver (color)|\
:am:bc=^H:bw:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:co#80:cr=^M:\
:do=^J:ho=\E[H:kb=^H:li#25:ll=\E[25H:nd=\E[C:\
:pt:se=\E[0;32m:so=\E[1m:ta=^I:up=\E[A:xt:
------------------------------------------------------------------------------
and that's it! Enjoy. I place this in the public domain, and would appreciate
feedback. Improvements and bug reports especially desired. If the code is too
cryptic or uncommented, feel free to send questions to:
Bennett Todd
...{decvax,ihnp4,akgua}!mcnc!ecsvax!bet